﻿using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Profiling;
using UnityEngine.UI;

public class Main : MonoBehaviour
{
    const int MAX = 5000;
    List<GameObject> mObjList = new List<GameObject>();
    // Start is called before the first frame update
    List<int> list = new List<int>(10);
    public byte[][] levelFootstepAndHitEffectGrid;
    public Dictionary<short, Dictionary<short, byte>> maps;


    public Text text;
    public Button addBtn;
    public Button moveBtn;
    public GameObject obj;
    private List<GameObject> list111 = new List<GameObject>();
    public Vector3[] list222;

    public Sprite sprite;
    public Material material;

    public bool forceFlush;
    private void Awake()
    {
        //for (int i = 0; i < 500; i++)
        //{
        //    Add();
        //}
        //for (int i = 0; i < 1; i++)
        //{
        //    Vector3 pos = new Vector3(Screen.width * Random.Range(-0.5f, 0.5f), Screen.height * Random.Range(-0.5f, 0.5f), 1);
        //    list222.Add(pos);
        //}
        //list222.Add(new Vector3(-Screen.width, -Screen.height, 1));
        //list222.Add(new Vector3(-Screen.width * 0f, -Screen.height * 0f, 1));
        //list222.Add(new Vector3(100, 100, 1));
        //list222.Add(new Vector3(200, 100, 1));
        //list222.Add(new Vector3(300, 100, 1));
        //list222.Add(new Vector3(-400, 100, 1));
        //list222.Add(new Vector3(500, 100, 1));
        SetTileMeshAsync(gameObject, sprite, list222);
    }

    public void Add()
    {
        GameObject temp = GameObject.Instantiate(obj, obj.transform.parent);
        float size = 20;
        temp.transform.position = new Vector3(Random.Range(-size, size), Random.Range(-size, size), 1);
        list111.Add(temp);
        text.text = list111.Count + "";
    }

    public void Remove()
    {
        GameObject obj = list111[0];
        list111.RemoveAt(0);
        GameObject.Destroy(obj);
        //text.text = list111.Count + "";
    }

    void Start()
    {
        Application.targetFrameRate = 60;

    }
    private static Vector2[] m_tilingUVs = new Vector2[]
   {
        new Vector2(0.0f, 1.0f),
        new Vector2(1.0f, 1.0f),
        new Vector2(0.0f, 0.0f),
        new Vector2(1.0f, 0.0f)
   };
    public void SetTileMeshAsync(GameObject tile, Sprite sp, Vector3[] pos)
    {
        MeshFilter meshFilter = tile.GetComponent<MeshFilter>();
        MeshRenderer meshRender = tile.GetComponent<MeshRenderer>();
        meshRender.sharedMaterial = material;
        meshRender.sharedMaterial.mainTexture = sp.texture;

        var mesh = meshFilter.mesh;
        if (mesh == null)
        {
            mesh = meshFilter.mesh = new Mesh();
        }
        else
        {
            mesh.Clear();
        }
        int vertexCount = pos.Length * 4;
        int indexCount = pos.Length * 6;
        var verts = new Vector3[vertexCount];
        var triangles = new int[indexCount];
        int vertexBufferIndex = 0, indexBufferIndex = 0;
        var uvs = new Vector2[vertexCount];

        float spW1 = sp.rect.width * 0.5f;
        float spH1 = sp.rect.height * 0.5f;
        //spW1 = spH1 = 0;
        Vector2 pivot = new Vector2(spW1, spH1);

        Vector4 size = new Vector4(float.MaxValue, float.MaxValue, float.MinValue, float.MinValue);
        List<Vector4> posList = new List<Vector4>();
        foreach (var p in pos)
        {
            float x = p.x;
            float y = p.y;
            if (size.x > x)
                size.x = x;
            if (size.y > y)
                size.y = y;
            if (size.z < x)
                size.z = x;
            if (size.w < y)
                size.w = y;
        }
        size.x -= pivot.x;
        size.z += sp.rect.width - pivot.x;
        size.y -= pivot.y;
        size.w += sp.rect.height - pivot.y;

        Vector4 realSize = size;
        size = size / sp.pixelsPerUnit;

        //foreach (var p in pos)
        {
            float wStart = size.x, wEnd = size.z;
            float hStart = size.y, hEnd = size.w;

            verts[vertexBufferIndex] = new Vector3(wStart, hEnd, 1.0f);
            verts[vertexBufferIndex + 1] = new Vector3(wEnd, hEnd, 1.0f);
            verts[vertexBufferIndex + 2] = new Vector3(wStart, hStart, 1.0f);
            verts[vertexBufferIndex + 3] = new Vector3(wEnd, hStart, 1.0f);

            triangles[indexBufferIndex] = vertexBufferIndex;
            triangles[indexBufferIndex + 1] = vertexBufferIndex + 1;
            triangles[indexBufferIndex + 2] = vertexBufferIndex + 2;
            triangles[indexBufferIndex + 3] = vertexBufferIndex + 2;
            triangles[indexBufferIndex + 4] = vertexBufferIndex + 1;
            triangles[indexBufferIndex + 5] = vertexBufferIndex + 3;

            float realW = realSize.z - realSize.x;
            float realH = realSize.w - realSize.y;

            float u = realW / sp.rect.width;
            float v = realH / sp.rect.height;

            float offsetX = realSize.x + pivot.x;
            float offsetY = realSize.y + pivot.y;

            //offsetX = offsetY = 0;
            Debug.LogError(realSize);
            foreach (var p in pos)
            {
                posList.Add(new Vector4(1f / sp.rect.width * (p.x - offsetX), 1f / sp.rect.height * (p.y - offsetY)));
            }

            meshRender.material.SetVector("_MainTex_ST", new Vector4(u, v));
            meshRender.material.SetVectorArray("_Flip", posList.ToArray());
            meshRender.material.SetFloat("_FlipCount", posList.Count);

            uvs[vertexBufferIndex] = m_tilingUVs[0];
            uvs[vertexBufferIndex + 1] = m_tilingUVs[1];
            uvs[vertexBufferIndex + 2] = m_tilingUVs[2];
            uvs[vertexBufferIndex + 3] = m_tilingUVs[3];


            mesh.vertices = verts;
            mesh.triangles = triangles;
            mesh.uv = uvs;
        }
    }

    private void Update()
    {
        if (forceFlush)
        {
            forceFlush = false;
            SetTileMeshAsync(gameObject, sprite, list222);
        }
        //list222.Clear();
        //list222.Add(ppp1);
        //SetTileMeshAsync(gameObject, sprite, list222.ToArray());
    }

    int frame = 0;
    int curframe = 0;
    float time = 0;
    private void OnGUI()
    {
        //GUILayout.Label(string.Format($"<size=20>电池总容量{Power.capacity}毫安,电压{Power.voltage}伏</size>"));
        //GUILayout.Label(string.Format($"<size=20>实时电流{e}毫安,实时功率{(int)(e * Power.voltage)},满电量能玩{((Power.capacity / e).ToString("f2"))}小时</size>"));

        //GUILayout.Label(string.Format($"使用时间:{(castTime * 1000)}"), GUILayout.MinWidth(200));
        //if (GUILayout.Button("当前" + funType))
        //{
        //    showTest1 = !showTest1;
        //}
        GUILayout.Space(120);
        if (GUILayout.Button("add", GUILayout.MinWidth(200), GUILayout.MinHeight(50)))
        {
            for (int i = 0; i < 10; i++)
                Add();

        }
        GUILayout.Space(120);
        if (GUILayout.Button("remove", GUILayout.MinWidth(200), GUILayout.MinHeight(50)))
        {
            for (int i = 0; i < 10; i++)
                Remove();
        }
        frame++;
        time += Time.deltaTime;
        if (time > 1f)
        {
            curframe = frame;
            frame = 0;
            time = 0f;
        }
        GUILayout.Button(string.Format($"<size=30>fps:{curframe} :  {list111.Count}</size>"), GUILayout.MinWidth(200), GUILayout.MinHeight(50));
    }

}
